import pyaudio
import wave
from pydub import AudioSegment
import os


def mp3_to_wav(mp3_path, wav_path="temp.wav", channels=2):
    """转换MP3为WAV格式并设置声道数"""
    audio = AudioSegment.from_mp3(mp3_path)
    # 强制转换声道数
    if channels == 1:
        audio = audio.set_channels(1)
    elif channels == 2:
        audio = audio.set_channels(2)
    audio.export(wav_path, format="wav")
    return wav_path


def stream_audio_to_mic(wav_path, virtual_device_name="CABLE Input"):
    p = pyaudio.PyAudio()

    # 获取设备信息
    device_index = -1
    device_channels = 2  # 默认假设2声道
    for i in range(p.get_device_count()):
        dev_info = p.get_device_info_by_index(i)
        if virtual_device_name in dev_info["name"]:
            device_index = dev_info["index"]
            # 获取设备支持的最大输出通道数
            device_channels = int(dev_info["maxOutputChannels"])
            print(f"找到设备: {dev_info['name']}, 支持通道数: {device_channels}")
            break

    if device_index == -1:
        # 打印所有设备帮助调试
        print("可用设备列表:")
        for i in range(p.get_device_count()):
            dev = p.get_device_info_by_index(i)
            print(
                f"{i}: {dev['name']}, 输入通道: {dev['maxInputChannels']}, 输出通道: {dev['maxOutputChannels']}"
            )
        raise RuntimeError(f"找不到虚拟设备: {virtual_device_name}")

    # 重新转换音频以匹配设备通道数
    converted_wav = "converted_temp.wav"
    mp3_to_wav(wav_path, converted_wav, channels=device_channels)

    wf = wave.open(converted_wav, "rb")

    # 验证参数
    print(
        f"音频参数: 通道数={wf.getnchannels()}, 采样宽度={wf.getsampwidth()}, 采样率={wf.getframerate()}"
    )

    try:
        stream = p.open(
            format=p.get_format_from_width(wf.getsampwidth()),
            channels=wf.getnchannels(),
            rate=wf.getframerate(),
            output=True,
            output_device_index=device_index,
        )

        # 流式传输音频
        chunk = 1024
        data = wf.readframes(chunk)

        while data:
            stream.write(data)
            data = wf.readframes(chunk)

    finally:
        # 确保资源清理
        if "stream" in locals() and stream.is_active():
            stream.stop_stream()
            stream.close()
        p.terminate()
        wf.close()
        # 清理临时文件
        if os.path.exists(converted_wav):
            os.remove(converted_wav)


if __name__ == "__main__":
    MP3_PATH = "sample4.wav"
    # 尝试不同设备名称变体
    DEVICE_NAMES = [
        "CABLE Output (VB-Audio Virtual Cable)",  # Windows常见名称
        "VB-Audio Virtual Cable",  # 备用名称
        "CABLE Input",  # 另一个常见名称
        "VoiceMeeter Input (VB-Audio VoiceMeeter VAIO)",  # 如果你使用VoiceMeeter
    ]
    if MP3_PATH.endswith(".mp3"):
        print("正在转换MP3为WAV...")
        wav_file = mp3_to_wav(MP3_PATH)
    elif MP3_PATH.endswith(".wav"):
        print("已传入WAV文件，无需转换")
        wav_file = MP3_PATH
    else:
        raise ValueError("请传入有效的MP3或WAV文件")

    success = False
    for device_name in DEVICE_NAMES:
        try:
            print(f"尝试设备: {device_name}")
            stream_audio_to_mic(wav_file, device_name)
            success = True
            print("音频传输成功!")
            break
        except Exception as e:
            print(f"设备 {device_name} 失败: {str(e)}")

    if not success:
        print("所有设备尝试失败，请检查:")
        print("1. 是否已安装VB-Cable?")
        print("2. 设备管理器中查看确切名称")
        print("3. 尝试管理员权限运行脚本")
